#ifndef __CONFIG_H
#define __CONFIG_H

#define MAX_CPUS 48

#define BALANCE_SPEED 0
#define BALANCE_LOAD 1
#define BALANCE_STATIC 2

typedef struct {
	// name of program to execute
	char exec_name[512];
	// arguments to program being executed
	char** exec_args;
	// the string of all the arges
	char exec_args_str[1024];
	// ids for the cpus to be used
	int cids[MAX_CPUS];
	// number of cpus is derived from the cids array
	int num_cpus;
	// if NOT_SET, it automatically discovers all the tasks. Otherwise it will produce an 
	// error if the number of tasks found does not match this number
	int num_tasks;
	// balance interval in seconds - make it too large and we can't balance effectively, 
	// make it too small and we won't get good information on running speeds. 
	double interval;
	// structure for doing nanosleep, etc with interval
	struct timespec interval_ts;
	// how much must the progress of a thread be below average for it to be regarded as behind
	double task_progress_threshold;
	// the maximum permissible variation in the update interval: a thread's elapsed realtime 
	// should not vary from the interval by more than this amount
	//	double interval_variation;
	// how many seconds to spend polling for all possible tasks
	double init_time;
	// should we allow internode numa migrations? 
	int enable_numa_migrate;
	// speed below which a thread is regarded as idle and ignored
	double idle_speed_limit;
	// can be set to speed balancing (the default), load balancing, or static
	int balancing;
	// check for errors
	int sanity_check;
	// take into account cpu idle time - only needed for apps that sleep
	int use_cpu_idle;
	// expected idle task - defaults to 0. should be set to 1 for OpenMP
	int expected_idle_task;
	// to start all tasks on one core 
	int no_init_spread;
	// add randomness to the balancing interval to prevent harmful synch with app
	int add_randomness;
	// the name of a file to read pids from. If this is null, launch the app to balance
	char pid_fname[512];
	// should we use the more efficient netlink interface? Usually needs root
	int use_netlink;
} config_t;

void get_config(int argc, char** argv, config_t* config);

#endif
